package com.telecom.sxint.app.api.controller.SystemController.App1SystemFileController;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;

public class ExcelMerge implements CellWriteHandler {
    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
        // 这个方法在创建单元格之前被调用，可以用来初始化行或列的样式
    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        // 这个方法在创建单元格之后被调用，可以用来设置单元格的样式或值
    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        if (isHead != null && isHead) {
            return; // 跳过头行
        }
        Sheet sheet = writeSheetHolder.getSheet();
        int rowIndex = cell.getRowIndex();
        int columnIndex = cell.getColumnIndex();
        mergeAll(sheet, cell);
    }

    private void mergeAll(Sheet sheet, Cell cell) {
        int rowIndex = cell.getRowIndex();
        int columnIndex = cell.getColumnIndex();

        Object cellValue =  getCellValue(cell);
        if (cellValue == null || cellValue.equals("") || isNumeric(cellValue.toString())) {
            return; // Skip blank, empty, or numeric cells
        }
        int mergeStartCol = columnIndex;
        int mergeStartRow = rowIndex;

        // Check left
        for (int i = columnIndex - 1; i >= 0; i--) {
            Cell nextCell = sheet.getRow(rowIndex).getCell(i);
            Object nextCellValue =  getCellValue(nextCell);
            if (nextCellValue == null || nextCellValue.equals("") || isNumeric(nextCellValue.toString())) {
                break;
            }
            if (cellValue.equals(nextCellValue)) {
                mergeStartCol = i;
            } else {
                break;
            }
        }


        // Check up
        for (int i = rowIndex - 1; i >= 0; i--) {
            Row nextRow = sheet.getRow(i);
            if (nextRow == null) {
                break;
            }
            Cell nextCell = nextRow.getCell(columnIndex);
            Object nextCellValue =  getCellValue(nextCell);
            if (nextCellValue == null || nextCellValue.equals("") || isNumeric(nextCellValue.toString())) {
                break;
            }
            if (cellValue.equals(nextCellValue)) {
                mergeStartRow = i;
            } else {
                break;
            }
        }

        mergeCells(sheet, mergeStartRow, mergeStartCol, rowIndex, columnIndex);
    }


    private Object getCellValue(Cell cell) {
        if (cell == null) {
            return null;
        }
        switch (cell.getCellType()) {
            case NUMERIC:
            case FORMULA:
                return cell.getNumericCellValue();
            case STRING:
                return cell.getStringCellValue();
            default:
                return "";
        }
    }

    private boolean isNumeric(String str) {
        try {
            Double.parseDouble(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    private void mergeCells(Sheet sheet, int startRow, int startCol, int endRow, int endCol) {
        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            if (range.isInRange(startRow, startCol) || range.isInRange(endRow, endCol)) {
                sheet.removeMergedRegion(i);
                i--;

            }
        }
        if (startRow != endRow || startCol != endCol) {
            sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, startCol, endCol));
        }
    }
}